The Apple Location Manager (ALM), version 1.0, was announced at MacWorld Expo in San Francisco on January 6, 1997 (see link at bottom for full text):
...
Apple Computer, Inc. today announced a free software utility for PowerBook computers called Apple Location Manager. Apple Location Manager software makes it easy for PowerBook users to move from one location to another without having to spend a lot of time manually reconfiguring their computer with every move.
"Mobile users, by definition, change location frequently. Apple Location Manager takes the difficulty out of moving from one place to another because with a single command, a user can reconfigure his or her system to the settings needed at any given location," said Dale Fuller, vice president and general manager for the PowerBook division. "It's a small piece of software, but it does a big job and saves people a lot of time and inconvenience. It's what Apple is all about...making complex tasks simple."
...
http://product.info.apple.com/pr/press.releases/1997/q2/970106.pr.rel.locmgr.html
As you may gather from the above excerpt, ALM provides a user interface for saving and restoring sets of settings so that PowerBook users can reconfigure their systems easily as they move from place to place.
Although ALM 1.0 ships with support for switching the default printer, TCP/IP settings, time zone, and a few other things, the ALM software is primarily an infrastructure for storing, retrieving, and applying sets of settings, and we expect third-party developers who are interested in meeting the needs of mobile users will be eager to use this framework to enhance their products, so we are providing this SDK.
Supporting ALM is not difficult - most of the time, you will not need to modify your product at all to add ALM support.
For most developers, "supporting" ALM means simply that - providing ALM with enough information to switch settings under user control in a way that is compatible with software that uses those settings. In addition to providing the infrastructure for making these changes, however, ALM also provides an API that developers can use to do a number of other things: applications can initiate switches, can request notification of switches while they are running, and can get information about user-defined sets of settings. These calls allow developer applications to become "location-aware" or they might be used to create "location-sensing" applications that could initiate switches automatically based on changes in the machine's environment.
Availability
Version 1.0 of ALM is available for download at the PowerBook Website, http://www.powerbook.apple.com/, where some third-party ALM efforts are also listed (there should be information at that site on how to get your stuff listed). This version runs only on 68030 or better PowerBooks (including all PowerPC PowerBooks) with System 7.6. For information on distributing any part of Apple Location Manager with your product, contact the Software Licensing Department: sw.license@apple.com. The evangelist for ALM is Doug MacMillan, standup@apple.com.
Version 1.0.1 of ALM is scheduled for inclusion in Mac OS 8, and its Apple Guide files will only work with Mac OS 8 (because it is a mixin guide).
Version 2.0, still early in development, should be available late in 1997. As announced at the WWDC hardware directions conference, ALM 2.0 will be enabled on desktop machines.
Acknowledgements
Many thanks to the entire ALM team for their tireless efforts in getting ALM into the hands of users and developers. Our collective thanks are also extended to third-party developers who participated in the seed program, without whose feedback and support ALM wouldn't be as useful nor as reliable as it is.
Installation
Provided with this SDK are debug and non-debug versions of ALM for your use in testing and development. Note that you should have Macsbug installed if you plan to install the debug build, since it is almost certain to generate a user break. The debug build is, however, not restricted to running on PowerBooks, while the non-debug build will only run on PowerBooks.
Interestingly, if you install the debug build first, you will then be able to install the non-debug build on a non-PowerBook, but the software will not run. This feature is a side-effect of allowing ALM to install on future PowerBooks, and is not to be considered a bug since end users should not have access to the debug build.
What goes where
Although using the installer is recommended, you may be interested in knowing where various pieces are placed, so here is a list of the pieces in the 1.0.1f6 install:
:System Folder:Control Panels:Location Manager
:System Folder:Control Strip Modules:Location Manager
:System Folder:Extensions:Location Manager Extension
:System Folder:Extensions:Location Manager Guide Addtns
:System Folder:Extensions:Location Manager Modules:Auto-Open Item
:System Folder:Extensions:Location Manager Modules:Default Printer
:System Folder:Extensions:Location Manager Modules:Extensions Mgr
:System Folder:Extensions:Location Manager Modules:File Sharing
:System Folder:Extensions:Location Manager Modules:Network
:System Folder:Extensions:Location Manager Modules:Sound
:System Folder:Extensions:Location Manager Modules:TimeZone
:System Folder:Extensions:Location Manager Modules:Internet Access
:System Folder:Preferences:Location Manager Prefs:Locations:SampleThese are, of course, localized for different countries. If you write modules, and you want to simplify their installation, your installation software may want to check for the presence or absence of the "Location Manager Extension", which is a file of type 'AINI' with creator 'walk'. If you find this file, you can install a module in the subfolder whose name is given in the STR# 128 resource at index position 20. This information is not guaranteed to remain at that spot (and I apologize for not having it in a more obvious place), but may be useful nonetheless; I do promise that, if that file and string is found, it will be as described above. If you do not find the file or string, you will have to fall back to your own semantics to decide whether or where to install, possibly using gestalt.
Using ALM
Once you have installed and restarted, open the control panel and play with some settings. ALM has comprehensive Balloon Help and Apple Guide support for your reference.
If you want to get a feel for how modules work, the SDK provides a sample module, which is compiled to "Generic" and can be used to create a custom module quickly for experimental purposes. We do not, however, recommend that you use this technique to create a "finished" module, particularly since the Generic module has not been heavily tested by any stretch of the imagination!
That said, a lot of what modules do is similar. The Generic module provided with this SDK can be quickly customized with your favorite resource editor to provide a working module for a wide range of software, under the assumption that the software maintains a preference file in its preferences folder. With these instructions, you could create a working module for software that follows the "preference file" model in about 10 minutes.
Before I describe the "customization", however, be aware that, as with most generic solutions, a module derived from Generic without material code changes is not going to be terribly efficient, both in speed and in memory use, and should not be considered the "preferred" means for supporting ALM. I encourage you to plan and design your own module, perhaps by modifying the Generic code itself.
With that said, also be aware that these instructions are "quick & dirty" - very little in the way of explanation is provided. So, make a copy of the Generic module, giving it an appropriate name. The Generic module is set up to store preferences for MicroSoft Word 5, and, although it is in a "working" state, there are some things that need to be tidied up, so if you'll go through that exercise, you'll have a good idea of how to customize the module for your own use.
- Open the Generic module in your favorite resource editor.
- Open 'thng' resource 128. Change the Component Subtype to a unique value. Normally, you will want to use the registered creator for your application, to avoid collisions. we'll use 'MSWD', the creator type of Word. You can also change the Component Manufacturer to whatever you wish. You don't need to change anything else.
- Open 'STR ' resource 10000. Change it to the name of your module, like "MicroSoft Word 5".
- Open 'STR ' resource 10001. Change the string there to a brief description of your module.
- If you are internationalizing your module, you can open 'intl' resource 10000, and change the script, region, language, and default font information for all text your module will return. This is a little bit more involved than I want to get right now, so we'll leave it alone, but it is not difficult to change when you need to.
- Open styled 'TEXT' resource 10000. Following the basic layout shown, type in descriptive information that the user will see in the ALM control panel when they click the Get Info button to find out about your module.
- Open the 'fils' resource 10000. This resource type contains files to consider as part of the setting, one to a resource.In our case, there is only one, it's name is "Word Settings (5)". There is also a companion resource with the same ID, and its type is 'rstr'; it contains an associated flags field telling the module whether the file, if changed, will require a restart or not (the reason these resources are separate has been lost in subsequent design changes, but I digress). If you have multiple files to deal with, you can put them all in separate resource pairs.
- It may seem like the module now has enough information to locate a preference, save and restore it, but there is one problem - what if MicroSoft Word is running? Open the 'apps' resource 10000. This is a list of applications to quit, if they are running, before accessing the preferences. In the case of our example, we'll send a quit event to the application both on getting the settings, and on retrieving them - presumably, we will explain this to the user in our Get Info. I'm sure you can see that it would be preferable to be able to "coexist" with the application so as to share the preferences file, but that does require writing a custom widget, obviously, and will have to be solved differently in every case. And besides, I promised there would be no code in this example.
- You could tidy your module up by deleting the TMPL resources and the custom icons (the custom icons are only there so that the icon will show without ALM installed - if it is installed, the Control Panel's bundle will provide the icon).
- You're done! Install your module in the Location Manager Modules folder and restart your machine.
Now that you've seen what you can do just by modifying the compiled Generic module, I hope you'll consider implementing your own module by modifying the Sample code, which is only slightly more involved (you believe me, don't you?).
Debugging Modules
Since installing modules normally requires restarting the machine, we provide developers a "shortcut" you can use to simplify testing modules, known as "Launch Time Loading". If you install the debug build of ALM, remove the Extension from the Extensions folder (and restart so that the extension is not currently loaded), and move it and the ALM Control Panel into your development folder. Then you can install your modules in a "Location Manager Modules" subfolder (that is, a subfolder of the folder you have the Control Panel and Extension in) and, each time you run the ALM Control Panel, your module will be dynamically reregistered. A reboot is necessary when the Extension is installed because the modules are registered by the Component Manager only at startup time. Replacing a module with a newer version in this case doesn't work because the Component Manager tracks registered modules by file ID, and replacing the module file changes the file ID.
Component Technology
The Component Manager is documented extensively in Inside Macintosh: More Macintosh Toolbox, and much of the discussion there I will either assume or ignore. See also the discussion of the 'thng' resource in the earlier section. Only three items are defined in the Rez header "LocationManager.r". The component type is kALMComponentType ('walk' for those who prefer graphical resource creation). The only other field of interest in the 'thng' resource are the "manufacturer flags", two of which are currently used in ALM:
#define kALMMultiplePerLocation 1 /* bit 0 */
#define kALMDescriptionGetsStale 2 /* bit 1 */Bit kALMMultiplePerLocation indicates that multiple instances of this module can be added to a location; this is how the Auto-Open Item is defined.
Bit kALMDescriptionGetsStale causes ALM to "re-query" a module, to get new descriptions more frequently. Usually, if the settings have not changed, ALM assumes the description has not changed either, but this may not be the case in some modules; for example, the Extensions Manager module is intelligent enough to report that the current extensions set has not changed if the user simply renamed it - the description would refer to the old name if this bit were not set.
All other bits are reserved.
One thing about the Component Manager I will reiterate here is that it is based on "single code resource" technology, and, as such there is one entry point, and the call type is specified by a selector. Negative selectors are defined by the Component Manager, and are used for component "Open" and "Close" calls, among others (see the sample code). Nonnegative selectors correspond to the ALM module API:
kALMGetCurrentSelect
kALMSetCurrentSelect
kALMCompareSettingSelect
kALMEditSettingSelect
kALMDescribeSettingsSelect
kALMDescribeErrorSelect
kALMImportExportSelect
kALMGetScriptInfoSelect
kALMGetInfoSelectAlso, in ALM, the convention is to set the "doAutoVersion" bit in the 'thng' resource. Otherwise, duplicate versions of your module may confuse the user, and potentially ALM itself.
You should be aware that, in order to reduce memory footprint, ALM does not keep modules around long, so you can expect modules to be opened and closed frequently - try to keep your module fast. Also, it is generally considered to be bad form to fail in component Open routine, so I suggest you defer most of your initialization to the first "real" call. Remember, if there is a problem, you want to be able to explain it to the user if at all possible, and that requires your component to open successfully.
Handling Global Data
ALM Component Manager-based calls come in two flavors: with global data passed as the first parameter, and without. The ALM header "LocationManager.k.h" provides a means for you do implement ALM calls either all one way, or all the other, using a combination of macros. Using these macros may help you transition your code if ALM were to be implemented using CFM. I recommend using the header in the following manner if you intend to pass global data using the Component Manager:
#define ALM_BASENAME()
#define ALM_GLOBALS() Globals
#ifndef __LOCATIONMANAGER_K__
#include <LocationManager.k.h>
#endif /* __LOCATIONMANAGER_K__ */You would then define the Globals data type, and expect it as the first parameter to your routines. And if you don't want global data, simply remove the second line above.
If you prefer to use "real" global data, you're on your own - consult the documentation for your development environment for ideas and strategies.
Options to Boot
Some modules require rebooting for the changes to take effect. To assess the impact of such changes, the module API lets ALM know if a reboot is required. If switching to a location involves a module requiring a reboot, ALM offers the user the chance to reboot, shutdown, or continue working after all modules are completed. There a number of options; for the most part, modules will return kALMNoChange (in the event the switch-to setting is the same as the current setting), kALMAvailableNow (in the event no rebooting is required), or kALMExtensions (in the event extensions need to be reloaded; this implies a restart in the current OS).
kALMNoChange
kALMAvailableNow
kALMFinderRestart
kALMProcesses
kALMExtensions
kALMWarmBoot
kALMColdBoot
kALMShutdownThe API Itself
This is the moment you've been waiting for - the definitions for each of the nine API calls a module may support (some are optional). In the following, I will assume you've followed the recommendation given above, and defined ALM_BASENAME() to nothing, so that these will be your routines, as prototyped for you in LocationManager.k.h (shown in both non-global and global format). While this summary may be good for reference, to get a feel for the calls I suggest you refer to the sample and explore its functionality.
GetCurrent
pascal ComponentResult GetCurrent (Handle setting);
pascal ComponentResult GetCurrent (Globals globals, Handle setting);When this call is made, the setting will already be allocated (but not the right size), so resize it as necessary; the format of your data is entirely private to you, and ALM simple stores the entire handle, whatever its size. Cast it to your private setting handle type and fill it with information describing whatever preferences your module cares about.
Return an error if the software you need isn't installed, or if the current setting suggests that the software isn't initialized (the Time Zone module, for example, returns an error if the current location has not been set.)
As stated previously, modules should Open even when the software the module works with isn't installed. You can then return an error from GetCurrent to tell the user what's wrong with the system.
SetCurrent
pascal ComponentResult SetCurrent (Handle setting, ALMRebootFlags* flags);
pascal ComponentResult SetCurrent (Globals globals, Handle setting,
ALMRebootFlags* flags);Set the current settings for your module; the setting passed in will be one previously returned to ALM on a GetCurrent call. Indicate via *flags what type of rebooting is necessary, if any.
CompareSetting
pascal ComponentResult CompareSetting (Handle setting1, Handle setting2,
Boolean* equal);
pascal ComponentResult CompareSetting (Globals globals, Handle setting1,
Handle setting2, Boolean* equal);Compare the contents of two settings. ALM uses this to determine if the setting your module is responsible for has changed and requires an update. Updates are currently only done by the user in the ALM Control Panel, but future versions may allow the user to update at other times when a change is detected.
EditSetting
pascal ComponentResult EditSetting (Handle setting);
pascal ComponentResult EditSetting (Globals globals, Handle setting);Interact with the user to modify the contents of the setting. Present whatever interface is necessary (launch your application, bring up your control panel, even show a movable modal in the ALM Control Panel's context). If you cause ALM to be put in the background, bring it to the foreground after the editing is done (this implies that you also need to know when editing is "done").
This call is currently optional; the Component Manager's "canDo" selector is used to determine if the module supports it or not. Although this call is optional, if you do not implement it, the user will be required to edit "live" settings to make changes, and then use the ALM Control Panel to update the setting; the user may find this confusing. We strongly encourage you to implement this call; future versions of ALM may require it, and your module might be disabled if it does not support EditSetting.
DescribeSettings
pascal ComponentResult DescribeSettings (Handle setting, StringHandle text);
pascal ComponentResult DescribeSettings (Globals globals, Handle setting,
CharsHandle text);Generate text which will be used in the location window to express what the setting represents. The description handle "text" will already be allocated. Resize it to fit the string you plan to return. The length of the text ALM displays is determined by the size of the description handle. The font information returned by GetScriptInfo will be used to display the text.
DescribeError
pascal ComponentResult DescribeError (OSErr lastErr, Str255 errStr);
pascal ComponentResult DescribeError (Globals globals, OSErr lastErr,
Str255 errStr);Generate a string which will be used in the location window (or the switch window) to describe an error. If you return paramErr, a generic routine will be used to describe the error. Make an attempt to describe the errors most likely to be returned by your various other routines. The technique Apple's modules use is to convert generic errors to specific ones; the Extensions Manager widget might translate certain instances of fnfErr (-43) to a private, positive number, which this routine might describe as "The Extensions Manager is not installed."
ImportExport
pascal ComponentResult ImportExport (Boolean import, Handle setting,
short resRefNum);
pascal ComponentResult ImportExport (Globals globals, Boolean import,
Handle setting, short resRefNum);This call is optional, however, modules that support it need only store sufficient information in the handle returned to a GetCurrent to effect a SetCurrent call. Supporting modules will be asked to convert their setting to a "complete" only when the user imports or exports a location.
If a module supports this call, it may be useful to define a field in the setting to indicate whether it is in exported or local form, assuming the data is all to be stored in the handle still.
If it is not convenient to have two forms of setting handle, you can UseResFile (resRefNum), to use the resource fork of the current import/export file, and add additional data as resources. To avoid resource collisions, you use your module's component signature as a reserved resource type.
GetScriptInfo
pascal ComponentResult GetScriptInfo (ALMScriptMgrInfo* info);
pascal ComponentResult GetScriptInfo (Globals globals, ALMScriptMgrInfo* info);This call gets information from the module that will allow ALM to display the various strings the module returns in the correctly localized script and region. Return the fields in accordance with how your module has been localized.
#pragma options align=mac68k
typedef struct {
SInt16 version;
SInt16 scriptCode;
SInt16 regionCode;
SInt16 langCode;
SInt16 fontNum;
SInt16 fontSize;
} ALMScriptMgrInfo;
#pragma options align=resetAlthough this call is optional, it is recommended that you implement it, along the style provided in the sample code. If you do not implement it, ALM will assume the current environment, something like this:
version = kALMScriptInfoVersion;
scriptCode = smSystemScript;
regionCode = GetScriptManagerVariable (smRegionCode);
langCode = GetScriptVariable(smSystemScript,
smScriptLang);
fontNum = GetScriptVariable(smSystemScript,
smScriptAppFond);
fontSize = GetScriptVariable(smSystemScript,
smScriptAppFondSize);GetInfo
pascal ComponentResult GetInfo (StringHandle* text, STHandle* style,
ModalFilterUPP filter);
pascal ComponentResult GetInfo (Globals globals, CharsHandle* text,
STHandle* style, ModalFilterUPP filter);This call is made when the user clicks the "Get Info" button in the location editing window.
It can return a text handle (and an optional style handle), or it can do its own thing, such as launching an external help system. The text will be displayed in a scrolling window.
Although ALM is, by itself, a fairly comprehensive software suite, it was recognized early in the design that if the framework were exposed, third-party developers could exploit some of ALM's internal workings to create customized solutions that we hadn't thought of. Also, during the development of modules, some common tasks began to emerge that we think other module developers would prefer not to reimplement.
In this SDK, you will find the header "LocationManager.h", interface "LocationManager.p" and even "LocationManager.a", if you are so inclined. If your project is PowerPC-based, you will need to link with the stub library LocationManagerLib. Weak linking is recommended; compare one of the seven exported routines against kUnresolvedCFragSymbolAddress (before calling any of them) to see if ALM is installed. Note that although the stub library does contain CFM-68K stubs, ALM 1.0 as currently distributed, including with this SDK, does not contain the corresponding CFM-68K implementation. For this reason, I recommend classic 68K development for now.
AppleScript
Although this is mentioned in the user's Read Me, if you prefer to speak AppleScript, it is possible to change the current location thusly:
tell
application "Finder"
open file ((control panels folderas
string) & "Location Manager")
tell
application "Location Manager"
set
current location
to
location myLocationName
end
tell
end
tell
If you see specific functionality that you think should be scripted, please use the bug reporter stack as described in Other Resources.
Determining if ALM is available
As with most things Mac, you should use gestalt to check for ALM (you do not need to do this in a module, since modules will only be called if ALM is around anyway, so checking would be somewhat redundant). Two gestalt selectors are defined: gestaltALMVers which returns the version of ALM installed in NumVersion format for your interest (get the pieces using the union NumVersionVariant.whole), and gestaltALMAttr which returns the attributes of ALM; you should test bit gestaltALMPresent to see if ALM is installed.
Managing Locations
Four routines are defined to let you examine the locations a user has defined.
pascal OSErr
ALMGetCurrentLocation(SInt16* index, ALMToken* token, Str31 name);Gets three values describing the current location. Pass NULL for any value you don't want. Index is zero-based; in ALM 1.0, there can be at most 16 locations, so *index will never be more than 15, but this may change in future releases. If there is no current location, the *index will be returned as kALMNoLocationIndex, *token will be kALMNoLocationToken, and the name will be "None (off)", as localized. An ALMToken is a private ALM data structure reference.
pascal OSErr
*
ALMGetIndLocation(SInt16 index, ALMTokentoken, Str31 name);
Use this call to index through the defined locations, returning their tokens and names. Note that you can pass kALMNoLocationIndex to get the localized version of the "None (off)" state. This function will return paramErr if the index is out of range. Again, pass NULL for any value you don't want returned.
pascal OSErr
*
ALMCountLocations(SInt16nLocations);
Returns the number of locations defined.
pascal OSErr
ALMSwitchToLocation(ALMToken newLocation, SInt32 switchFlags);Initiates a location switch. The switchFlags parameter is a set of flags that control switching options. Use kALMDefaultSwitchFlags for a normal switch or kALMDontShowStatusWindow for a "quiet" switch that does not put up the dialog box (not recommended).
If you are not sure about the environment in which you will be switching (for example, you are inside a background process, or inside a process that doesn't respond well to having a dialog suddenly popup inside its context), add the flag kALMSignalViaAE and the switch will be deferred until the Finder (or the Location Manager Control Panel) is the current process. The flag is so-named because the context is guaranteed by sending an AppleEvent since the Finder won't process an AppleEvent while it is not the current process!
Detecting Switches
ALM sends events to all AE-aware applications currently running whenever a switch occurs. The event has an AEEventClass of kAECoreSuite and an AEEventID of kAESystemConfigNotice. The event contains a parameter keyed under kAELocationNotice, which is a 32-bit quantity representing an ALMToken. If you are not an application (no, not you personally, but surely you view yourself as your code, right?), you can use the following routines to register a callback routine for notification:
pascal OSErr
*
ALMRegisterNotifyProc(ALMNotificationUPP notificationProc,
const ProcessSerialNumberwhichPSN);
pascal OSErr
*
ALMRemoveNotifyProc(ALMNotificationUPP notificationProc,
const ProcessSerialNumberwhichPSN);
You create an ALMNotificationUPP using the conventional myRoutineUPP = NewALMNotificationProc(MyALMNotificationRoutine), and dispose of it with DisposeRoutineDescriptor(myRoutineUPP). Your routine should conform to this interface:
pascal void
*
MyALMNotificationRoutine(AppleEventtheEvent);
Extract kAELocationNotice from theEvent in the same fashion as you would in an AEHandler.
Module Import Collisions
As discussed earlier, where preferences supported by a module keep track of named configurations, such as under Open Transport or Extensions Manager, the module should only keep track of the name of that configuration, until it needs to do an export. The problem becomes, then, that an Importing user might have a setting with the same name that is not the same setting. Obviously, it would not be good to blindly overwrite the existing setting. So, ALM provides the above call so that a module may prompt the user, without going through the general hassle of setting up a user interface within a code resource, for a new name (or to replace the old name).
pascal OSErr
ALMConfirmName(ConstStr255Param msg, Str255 configName,
SInt16* choice, ModalFilterUPP filter);
Typically, the module developer will call this routine with msg as a message indicating the conflict occurred. If a ^0 is embedded within the string, it will be replaced with the configName parameter for presentation to the user in the dialog (for example, if msg is "The config named "^0" exists." and configName is "MyConfig", the user sees a dialog with "The config named "MyConfig" exists."). If the user chooses to rename the config, the new name is returned in configName, and *choice is set to ALMConfirmRenameConfig; you should then check to see that the user hasn't collided with yet another config, possibly making this call again. If the user chooses to replace the config, you will get *choice of ALMConfirmReplaceConfig. The only other possibility is that the user cancels the whole operation, in which case the function returns userCanceledErr and *choice is not defined.
The final parameter, filter, is a standard dialog filter that you can use to filter events; set it to NULL otherwise. In ALM 1.0.x, the filter function is only called while the second dialog is up. This is a bug; future versions will call your filter function during both dialogs' tenure. If the refcon of the dialog is zero, you can presume you are being called from ALM 1.0.x; if it is nonzero, then you are under a later version of ALM.
Errors
Listed here for completeness; most of these are unremarkable, although note that a module that cannot switch at startup time should return ALMDeferSwitchErr if it cannot handle a SetCurrent call at boot time. Generally, modules should only return errors that can be translated into informative messages to users via the DescribeError call.
ALMInternalErr = -30049
ALMLocationNotFound = -30048
ALMNoSuchModuleErr = -30047
ALMModuleCommunicationErr = -30046
ALMDuplicateModuleErr = -30045
ALMInstallationErr = -30044
ALMDeferSwitchErr = -30043
Shared Library Model
ALM has a long genesis, and currently uses the Component Manager to implement modules. In keeping with Apple's Dynamic Linked Library Statement of direction, a future version of ALM is likely to support CFM (see http://devtools.apple.com/eto/ProductInfo/DLLdirectional.html ), but Component Manager modules will probably continue to be supported simultaneously for a period of time to protect users' investment in your software.
Use on the Desktop
As originally conceived, ALM was targeted at mobile users who move their computers from place to place and were faced with the unpleasant chore of switching settings in several different control panels every time they sat down; for this reason, version 1.0.x only runs on PowerBooks. Version 2.0 will also run on Desktop machines.
Name/UI Change
It is possible that ALM 2.0 will not refer to "Locations" or even be called "Apple Location Manager", since such a name does not convey sufficient meaning on desktop machines. In addition, the User Interface contemplated for ALM 2.0 is somewhat different from that of 1.0.x. For both of these reasons, it is advisable to avoid making reference to specifics of the name or UI that might be changed.
AppleGuide
As it stands now, there is no easy way to provide AppleGuide and have it "mixin" to the Mobility topic ALM uses. I therefore suggest that your ALM AppleGuide content be located within the guide for your product.
Rhapsody
At this writing, it is not clear exactly how ALM will fit in to Apple's next generation OS, since ALM evolved in System 7. It is likely that ALM will work in Rhapsody's backward-compatibility environment, but we would be interested in hearing from developers and users about how ALM or ALM technology might be used under "native" Rhapsody.
Inside Macintosh: Apple Location Manager
There shall be no such book.
ALM Developers
Other companies have already written Location Manager modules:
Network TeleSystems, Inc. Location Manager Modules
The NTS PPP module 3.0 (free) allows switching of NTS PPP configurations. It requires NTS PPP version 3.0, which is available, free, on the Network Telesystems website. The NTS PPP module 4.0 (free) allows switching of TunnelBuilder and TCP Pro settings.Prime Computing Solutions Location Manager Modules
Prime Computing has released two modules (shareware): one for OT/PPP and Modem settings, and one for MacPPP and FreePPP settings.Reporting Bugs and Requests
If you find a problem or have a suggestion to make with respect to ALM or the SDK, please submit your report to devsupport@apple.com.
Reference Material
Techniques for Writing and Debugging Components, develop 12.
Component Manager, Inside Macintosh: More Macintosh Toolbox.
ALM article planned for an upcoming issue of develop. Date of publication not currently known.